#include "MainWindow.h"
#include "DotView.h"
#include "../Models/DotModel.h"
#include "../Controllers/DotController.h"
#include <QScrollArea>
#include <QDockWidget>
#include <QStatusBar>
#include <QAction>
#include "ControlPanel.h"
#include "../Views/StatusViewer.h"
#include <QApplication>
#include <QMessageBox>
#include "../Utils/Msg.h"
#include <QVBoxLayout>
#include "PlayingInfoViewer.h"
#include "../Utils/ResultLogger.h"
#include "BuddyWnd.h"
#include "../Network/NetworkManager.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setAttribute(Qt::WA_AcceptTouchEvents);

    mpView = new DotView();
    mpModel = new DotModel();
    mpController = new DotController(mpView,mpModel);

    //Central Widget : Title && Play Ground
    mpScrollArea = new QScrollArea();
    mpScrollArea->setAlignment(Qt::AlignCenter);
    mpScrollArea->setWidget(mpView);
    QVBoxLayout *pCWLayout = new QVBoxLayout();
    PlayingInfoViewer *pPIV = new PlayingInfoViewer(mpController);
    pPIV->setFixedHeight(25);
    pCWLayout->addWidget(pPIV);
    pCWLayout->addWidget(mpScrollArea);
    QWidget *pCW = new QWidget();
    pCW->setLayout(pCWLayout);
    setCentralWidget(pCW);

    //Controllpanel
    mpDockWidgetCtrlPnl = new QDockWidget(tr("Control Panel"),this);
    mpDockWidgetCtrlPnl->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    mpCtrlPnl = new ControlPanel(this);
    mpDockWidgetCtrlPnl->setMaximumWidth(400);
    mpDockWidgetCtrlPnl->setWidget(mpCtrlPnl);
    addDockWidget(Qt::DockWidgetArea(GameSettings::me()->setting(Game::CtrlPnlArea).value<int>()), mpDockWidgetCtrlPnl);
    QAction *pCtrlPnlAction = mpDockWidgetCtrlPnl->toggleViewAction();
    pCtrlPnlAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
    this->addAction(pCtrlPnlAction);

    // Buddy Panel
    mpDockWidgetBuddyPnl = new QDockWidget(tr("Buddy Panel"));
    mpDockWidgetBuddyPnl->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    mpBuddyPnl = new BuddyWnd();
    mpBuddyPnl->setNetManager(mpController->netManager());
    mpDockWidgetBuddyPnl->setMaximumWidth(400);
    mpDockWidgetBuddyPnl->setWidget(mpBuddyPnl);
    //addDockWidget(Qt::RightDockWidgetArea,mpDockWidgetBuddyPnl);
    Qt::DockWidgetArea docArea =Qt::DockWidgetArea(GameSettings::me()->setting(Game::BuddyPnlArea).value<int>());
    docArea = docArea == Qt::LeftDockWidgetArea ? Qt::LeftDockWidgetArea : Qt::RightDockWidgetArea;
    addDockWidget(docArea,mpDockWidgetBuddyPnl);
    QAction *pActBuddyToggle = mpDockWidgetBuddyPnl->toggleViewAction();
    pActBuddyToggle->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
    this->addAction(pActBuddyToggle);

    //Actions
    QAction *pHowToPlay = new QAction("How to play?",this);
    pHowToPlay->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_I));
    this->addAction(pHowToPlay);

    QAction *pShowCommands = new QAction("Show Commands",this);
    pShowCommands->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_K));
    this->addAction(pShowCommands);

    QAction *pActResultLog = new QAction("Playing Log",this);
    pActResultLog->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
    this->addAction(pActResultLog);

    QAction *pActAbout = new QAction("About Dot",this);
    pActAbout->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_A));
    this->addAction(pActAbout);

    //SIG-SLOT Binding
    connect(pActResultLog,SIGNAL(triggered()),ResultLogger::me(),SLOT(showLog()));
    connect(QApplication::instance(),SIGNAL(lastWindowClosed()),GameSettings::me(),SLOT(savePreference()));
    connect(mpController,SIGNAL(gameStarted()),mpCtrlPnl,SLOT(gameStarted()));
    connect(mpController,SIGNAL(gameFinished(Game::Player)),mpCtrlPnl,SLOT(gameFinished(Game::Player)));
    connect(mpController,SIGNAL(gameCanceled()),mpCtrlPnl,SLOT(gameCanceled()));
    connect(pHowToPlay,SIGNAL(triggered()),mpView,SLOT(showHowToPlay()));
    connect(pShowCommands,SIGNAL(triggered()),mpView,SLOT(showCommands()));
    connect(pActAbout,SIGNAL(triggered()),SLOT(showAboutDot()));
    connect(mpController,SIGNAL(gameCanceled()),SLOT(gameCanceled()));
    connect(mpController,SIGNAL(networkGamePlayingViewInfoChanged(QString,QColor)),mpCtrlPnl,SLOT(networkGamePlayingViewInfoChanged(QString,QColor)));
    connect(mpController,SIGNAL(networkGameStartingParameterRequest(int,int,QString,QColor)),mpCtrlPnl,SLOT(networkGameStartingParameterRequest(int,int,QString,QColor)));
    connect(mpBuddyPnl,SIGNAL(askForPlaying(Connection*)),mpController,SLOT(askForPlaying(Connection*)));
    connect(mpController->netManager(),SIGNAL(newMsgCame()),SLOT(newMsgCame()));

    //Statusbar
    StatusViewer::me(statusBar(),mpController);
    this->move(GameSettings::me()->setting(Game::WindowPosition).toPoint());
    QSize size = GameSettings::me()->setting(Game::WindowSize).toSize();

    this->resize(size);
    gameCanceled();
    mpView->setHowToPlayEnabled(true);
    mpDockWidgetCtrlPnl->setVisible(GameSettings::me()->setting(Game::CtrlPnlVisible).value<bool>());
    mpDockWidgetBuddyPnl->setVisible(GameSettings::me()->setting(Game::BuddyPnlVisible).value<bool>());
    setWindowIcon(QIcon(QLatin1String(":res/res/dot.png")));
}

MainWindow::~MainWindow()
{
    delete mpModel;
    delete mpController;
    delete mpView;
}

void MainWindow::closeEvent(QCloseEvent *pEvent)
{           
    if(Msg::ask("Are you sure to close?",mpController->isGameRunning() ? "A playing session is running." : "") == QMessageBox::No){
        pEvent->ignore();
    }

    if(!mpCtrlPnl->aMomentBeforeClosing()){
        pEvent->ignore();
    }

    GameSettings::me()->setSetting(Game::CtrlPnlVisible,mpDockWidgetCtrlPnl->isVisible());
    GameSettings::me()->setSetting(Game::CtrlPnlArea,int(dockWidgetArea(mpDockWidgetCtrlPnl)));
    GameSettings::me()->setSetting(Game::BuddyPnlVisible,mpDockWidgetBuddyPnl->isVisible());
    GameSettings::me()->setSetting(Game::BuddyPnlArea,int(dockWidgetArea(mpDockWidgetBuddyPnl)));
}

void MainWindow::showAboutDot()
{
    QString strTxt = "A simple game that we used to play at our childhood time.\n\n Developed by kernel.writer@gmail.com";
    QMessageBox::about(this,"About 'Dot Game'",strTxt);
}

void MainWindow::gameCanceled()
{
    mpView->resize(mpScrollArea->size() - QSize(100,50));
}

void MainWindow::newMsgCame()
{
    this->activateWindow();
}
